---
title: "Python3 简单HTTP服务器"
date: 2018-10-30
categories:
- python
tags:
---

<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orga244f9a">启动静态文件服务器</a></li>
<li><a href="#org38e8320">自定义Web服务器</a>
<ul>
<li><a href="#orga0e5942">FAQ</a>
<ul>
<li><a href="#org1485e08">如何更改路径</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-orga244f9a">
<h2 id="orga244f9a">启动静态文件服务器</h2>
<div class="outline-text-2" id="text-orga244f9a">
<p>
启动一个静态文件服务器，Web服务器的根目录为当前目录
</p>
<blockquote>
<p>
<a href="https://stackoverflow.com/questions/7943751/what-is-the-python-3-equivalent-of-python-m-simplehttpserver">https://stackoverflow.com/questions/7943751/what-is-the-python-3-equivalent-of-python-m-simplehttpserver</a>
</p>
</blockquote>
<pre class="example">
# python3
python3 -m http.server
# python2
python -m SimpleHTTPServer
</pre>
</div>
</div>
<div class="outline-2" id="outline-container-org38e8320">
<h2 id="org38e8320">自定义Web服务器</h2>
<div class="outline-text-2" id="text-org38e8320">
<p>
python3 使用 SimpleHTTPRequestHandler（python2中为SimpleHTTPServer）
</p>
<blockquote>
<p>
<a href="https://docs.python.org/3/library/http.server.html#http.server.HTTPServer">https://docs.python.org/3/library/http.server.html#http.server.HTTPServer</a>
<a href="https://stackabuse.com/serving-files-with-pythons-simplehttpserver-module/">https://stackabuse.com/serving-files-with-pythons-simplehttpserver-module/</a>
</p>
</blockquote>
<div class="org-src-container">
<pre class="src src-python"><span style="font-weight: bold;">from</span> http.server <span style="font-weight: bold;">import</span> HTTPServer, SimpleHTTPRequestHandler
<span style="font-weight: bold;">import</span> http.client

<span style="font-weight: bold;">class</span> <span style="font-weight: bold; text-decoration: underline;">HttpHandler</span>(SimpleHTTPRequestHandler):

    <span style="font-weight: bold;">def</span> <span style="font-weight: bold;">do_GET</span>(<span style="font-weight: bold;">self</span>):
        <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">处理特定的url执行指定的逻辑</span>
        <span style="font-weight: bold;">if</span> <span style="font-weight: bold;">self</span>.path == <span style="font-style: italic;">"/"</span>:
            <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">self.path 能被赋值，从而改变路径</span>
            <span style="font-weight: bold;">print</span>(<span style="font-style: italic;">"Index"</span>)
        <span style="font-weight: bold;">else</span>:
            <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">其余的调用父类do_GET方法，执行默认的逻辑</span>
            SimpleHTTPRequestHandler.do_GET(<span style="font-weight: bold;">self</span>)


    <span style="font-weight: bold;">def</span> <span style="font-weight: bold;">do_POST</span>(<span style="font-weight: bold;">self</span>):

        <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">POST handler</span>
        <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">begin header</span>
        <span style="font-weight: bold;">self</span>.send_response(200)
        <span style="font-weight: bold;">self</span>.send_header(<span style="font-style: italic;">"Content-Type"</span>, <span style="font-style: italic;">"text/plain"</span>)
        <span style="font-weight: bold;">self</span>.end_headers()
        <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">begin resposne body</span>
        <span style="font-weight: bold;">self</span>.wfile.write(<span style="font-weight: bold;">bytes</span>(<span style="font-style: italic;">"message"</span>))
        <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">对像中包括了server对像，控制http server</span>
        <span style="font-weight: bold;">self</span>.server.stop()
        <span style="font-weight: bold;">pass</span>


<span style="font-weight: bold;">def</span> <span style="font-weight: bold;">main</span>():
    <span style="font-weight: bold; font-style: italic;"># </span><span style="font-weight: bold; font-style: italic;">构造HTTPServer需要指定SimpleHTTPRequestHandler的类，不是对像</span>
    <span style="font-weight: bold; font-style: italic;">server</span> = HTTPServer((<span style="font-style: italic;">'localhost'</span>, 9315), HttpHandler)
    server.serve_forever()

<span style="font-weight: bold;">if</span> <span style="font-weight: bold;">__name__</span> == <span style="font-style: italic;">"__main__"</span>:
    main()

</pre>
</div>
<p>
HTTPServer对象需要一个HTTPHandler的类，而不是该类的实例。
</p>
<p>
Python提供了一个简单的 SimpleHTTPRequestHandler ，通过继承这个类，能够定义HTTP请求处理器。
</p>
<p>
在SimpleHTTPRequestHandler中，能够使用self.server获取到HTTPServer的对象。
</p>
</div>
<div class="outline-3" id="outline-container-orga0e5942">
<h3 id="orga0e5942">FAQ</h3>
<div class="outline-text-3" id="text-orga0e5942">
</div>
<div class="outline-4" id="outline-container-org1485e08">
<h4 id="org1485e08">如何更改路径</h4>
<div class="outline-text-4" id="text-org1485e08">
<p>
例如访问 /static/js/jquery.js，而对应的文件在 ./js/jquery.js。
在 do_GET 方法中， self.path 不仅能获取，也能给它设置新的值
</p>
<div class="org-src-container">
<pre class="src src-py">class HttpHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
	if self.path.startswith('/static/'):
	    self.path = self.path[7:]
	# 更改了路径后让父类继续处理
	return http.server.SimpleHTTPRequestHandler.do_GET(self)
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="date">Date: 2018-10-30</p>
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
